﻿
using System.DrawingCore;
using System.DrawingCore.Printing;
using System.Text;
using static LabelPrint.Controllers.WeatherForecastController;

namespace LabelPrint.Utility
{
    public static class PrintHelper
    {
        #region #########第一种#############
        //定义一个字符串流，用来接收所要打印的数据
        private static StringReader sr;
        //str要打印的数据
        public static bool Print(string str)
        {
            bool result = true;
            try
            {
                sr = new StringReader(str.ToString());
                PrintDocument pd = new PrintDocument();
                pd.PrintController = new System.DrawingCore.Printing.StandardPrintController();
                pd.DefaultPageSettings.Margins.Top = 2;
                pd.DefaultPageSettings.Margins.Left = 0;
                //pd.DefaultPageSettings.PaperSize.Width = 320;
                //pd.DefaultPageSettings.PaperSize.Height = 5150;
                pd.PrinterSettings.PrinterName = pd.DefaultPageSettings.PrinterSettings.PrinterName;//
                //默认打印机
                pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
                pd.Print();
            }
            catch (Exception ex)
            {
                result = false;
            }
            finally
            {
                if (sr != null)
                    sr.Close();
            }
            return result;
        }

        private static void pd_PrintPage(object sender, PrintPageEventArgs ev)
        {
            Font printFont = new Font("Arial", 9);//打印字体
            float linesPerPage = 0;
            float yPos = 0;
            int count = 0;
            float leftMargin = ev.MarginBounds.Left;
            float topMargin = ev.MarginBounds.Top;
            String line = "";
            linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics);
            while (count < linesPerPage && ((line = sr.ReadLine()) != null))
            {
                yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
                ev.Graphics.DrawString(line, printFont, Brushes.Black,
                leftMargin, yPos, new StringFormat());
                count++;
            }
            // If more lines exist, print another page.
            if (line != null)
                ev.HasMorePages = true;
            else
                ev.HasMorePages = false;
        }
        #endregion

        #region #############第二种###############
        public class TickDTO
        {
            /// <summary>
            /// 商品名称
            /// </summary>
            public string Name { get; set; }

            /// <summary>
            /// 单价
            /// </summary>
            public decimal Price { get; set; } = 0.0M;

            /// <summary>
            /// 数量
            /// </summary>
            public int Num { get; set; } = 0;

            /// <summary>
            /// 金额
            /// </summary>
            public decimal Money { get; set; } = 0.0M;

        }
        public static List<TickDTO> GetList()
        {
            return new List<TickDTO>()
            {
                new TickDTO()
                {
                    Name="笔记本",
                    Price=15.6M,
                    Num=1,
                    Money=15.6M
                },
                 new TickDTO()
                {
                    Name="铅笔(晨光)",
                    Price=1M,
                    Num=1,
                    Money=1M
                },
                  new TickDTO()
                {
                    Name="圆珠笔",
                    Price=2.5M,
                    Num=1,
                    Money=2.5M
                },
                  new TickDTO()
                {
                    Name="书包",
                    Price=99.9M,
                    Num=1,
                    Money=99.9M
                },
                  new TickDTO()
                {
                    Name="修正液",
                    Price=5M,
                    Num=1,
                    Money=5M
                },
                  new TickDTO()
                {
                    Name="透明胶带",
                    Price=2M,
                    Num=1,
                    Money=2M
                },
                  new TickDTO()
                {
                    Name="圆规",
                    Price=25M,
                    Num=1,
                    Money=25M
                },
                  new TickDTO()
                {
                    Name="纸贴",
                    Price=1M,
                    Num=1,
                    Money=1M
                },
                  new TickDTO()
                {
                    Name="毛笔(细)",
                    Price=5M,
                    Num=1,
                    Money=5M
                },
                  new TickDTO()
                {
                    Name="墨水",
                    Price=5M,
                    Num=1,
                    Money=5M
                },
                  new TickDTO()
                {
                    Name="耳机",
                    Price=19.9M,
                    Num=1,
                    Money=19.9M
                },
                new TickDTO()
                {
                    Name="橡皮",
                    Price=0.80M,
                    Num=1,
                    Money=0.80M
                },
                new TickDTO()
                {
                    Name="三角板",
                    Price=6.00M,
                    Num=1,
                    Money=6.00M
                },
                 new TickDTO()
                {
                    Name="香飘飘奶茶(原味)",
                    Price=6.00M,
                    Num=1,
                    Money=6.00M
                },
                  new TickDTO()
                {
                    Name="香飘飘奶茶(红豆味)",
                    Price=6.00M,
                    Num=1,
                    Money=6.00M
                }
            };
        }
        /// <summary>
        /// 结算小品打印
        /// </summary>
        public static void Myprinter_JS()
        {
            PrintDocument pd = new PrintDocument();
            //pd.PrintPage += new PrintPageEventHandler(button_print_Click);
            pd.PrintPage += new PrintPageEventHandler(printDocument_PrintA4Page_JS);

            //pd.DefaultPageSettings.PrinterSettings.PrinterName = "ZDesigner GX430t";//打印机名称
            //pd.DefaultPageSettings.Landscape = true;  //设置横向打印，不设置默认是纵向的
            pd.PrintController = new System.DrawingCore.Printing.StandardPrintController();
            pd.Print();
        }

        public static void printDocument_PrintA4Page_JS(object sender, PrintPageEventArgs e)
        {
            int y = 10;
            int x = 20;
            int fontsize = 11;
            int spacing = 10;
            int cellspacing = 60;
            int endspacing = fontsize+spacing;
            int strspacing = 20;
            Font titleFont = new Font("黑体", fontsize, FontStyle.Bold);//标题字体           
            Font fntTxt = new Font("宋体", fontsize-1, FontStyle.Regular);//正文文字                  
            Brush brush = new SolidBrush(Color.Black);//画刷
            //实线画笔
            Pen pen = new Pen(Color.Black);//线条颜色
            //虚线画笔
            Pen pen2 = new Pen(Color.Black);
            pen2.DashStyle = System.DrawingCore.Drawing2D.DashStyle.Dash;
            string filename = DateTime.Now.ToString("yyyyMMddHHmmssffffff")+".gif";
            string url = "D:\\项目\\项目功能模块\\ClassLibrary\\LabelPrint\\LabelPrint\\wwwroot\\images\\"+filename;
            try
            {
                var list = GetList();
                decimal usermoney = 500.00M;
                decimal total = list.Sum(x => x.Money);
                decimal returnmoney = usermoney - total;
                e.Graphics.DrawString("         华润万家", titleFont, brush, new Point(x, y));
                e.Graphics.DrawString("生活超市       欢迎惠顾", titleFont, brush, new Point(x, y+fontsize+spacing));
                e.Graphics.DrawString("品名", fntTxt, brush, new Point(x, y+fontsize*3+spacing));
                e.Graphics.DrawString("单价(元)", fntTxt, brush, new Point(x+cellspacing+strspacing, y+fontsize*3+spacing));
                e.Graphics.DrawString("数量", fntTxt, brush, new Point(x+cellspacing*2+strspacing, y+fontsize*3+spacing));
                e.Graphics.DrawString("金额(元)", fntTxt, brush, new Point(x+cellspacing*3, y+fontsize*3+spacing));
                int count = 4;
                foreach (var p in list)
                {
                    e.Graphics.DrawString(p.Name.Length>6 ? p.Name.Substring(0, 6) : p.Name, fntTxt, brush, new Point(x, y+(endspacing)*count));
                    e.Graphics.DrawString(p.Price.ToString(), fntTxt, brush, new Point(x+cellspacing+strspacing, y+(endspacing)*count));
                    e.Graphics.DrawString(p.Num.ToString(), fntTxt, brush, new Point(x+cellspacing*2+strspacing, y+(endspacing)*count));
                    e.Graphics.DrawString(p.Money.ToString(), fntTxt, brush, new Point(x+cellspacing*3, y+(endspacing)*count));
                    count++;
                }
                int countstr = list.Count+3;
                Point[] points111 = { new Point(x, y+endspacing*(countstr+1)), new Point(x*12, y+endspacing*(countstr+1)) };
                e.Graphics.DrawCurve(pen2, points111);
                e.Graphics.DrawString("应收"+total+"元 优惠0元", fntTxt, brush, new Point(x, y+endspacing*(countstr+2)));
                e.Graphics.DrawString("实收"+usermoney+"元 找零"+returnmoney+"元", fntTxt, brush, new Point(x, y+endspacing*(countstr+3)));
                e.Graphics.DrawString("欠款当面核对 质量问题凭小票退换", fntTxt, brush, new Point(x, y+endspacing*(countstr+4)));
                Point[] points222 = { new Point(x, y+endspacing*(countstr+5)), new Point(x*12, y+endspacing*(countstr+5)) };
                e.Graphics.DrawCurve(pen2, points222);
                System.DrawingCore.Bitmap bitmap = MakeTXCode.CreateQrCode("123456", url, 200, 180);
                e.Graphics.DrawImage(bitmap, new Point(0, y+endspacing*(countstr+5)+10));

            }
            catch (Exception ee)
            {
                throw new Exception(ee.Message.ToString());
            }
        }

        #endregion

        #region #############第三种################
        private static void button_print_Click(object sender, PrintPageEventArgs e)
        {
            if (e.Graphics == null) { throw new NullReferenceException("e.Graphics 是空值"); }

            float rowWidth = 285.0F;

            // 字体高度
            float fontHeight = 11.0F;

            // 如果完全用字体高度来计算可能最后一行会有部分 显示不全 这里保底 留点间距
            float bottomMargin = fontHeight;
            string PrintTime = DateTime.Now.ToString("yyyy/HH/mm-ss");
            var list = GetList();
            var drawStrings = new List<string>{
                "<b>华润万家<c>",
                "祝你生活愉快~欢迎下次光临",
                PrintTime,
                "规格       商品         数量 价格",
                "1杯/*香飘飘奶茶(原味)*   *1  ￥6",
                "1杯/*香飘飘奶茶(红豆味)* *1  ￥6",
                "1箱/*蒙牛纯牛奶*         *1  ￥33",
            };


            Font drawFont = new Font("黑体", fontHeight);
            SolidBrush drawBrush = new SolidBrush(Color.Black);
            float x = 0F;
            float y = 0F;
            StringFormat stringFormat = new StringFormat();
            foreach (var item in drawStrings)
            {
                var drawString = item;
                // 是否加粗
                if (drawString.Contains("<b>"))
                {
                    drawFont = new Font("黑体", fontHeight, FontStyle.Bold);
                    drawString = drawString.Replace("<b>", "");
                }
                else
                {
                    drawFont = new Font("黑体", fontHeight);
                }
                // 是否居中
                if (drawString.Contains("<c>"))
                {
                    stringFormat.Alignment = StringAlignment.Center;
                    drawString = drawString.Replace("<c>", "");
                }// 是否居右
                else if (drawString.Contains("<r>"))
                {
                    stringFormat.Alignment = StringAlignment.Far;
                    drawString = drawString.Replace("<r>", "");
                }
                else
                {
                    stringFormat.Alignment = StringAlignment.Near;
                }
                // 获取行高
                var rowHeight = GetTrueHight(drawString, stringFormat, drawFont, e.Graphics, rowWidth, fontHeight) + bottomMargin;

                RectangleF drawRect = new RectangleF(x, y, rowWidth, rowHeight);

                e.Graphics.DrawString(drawString, drawFont, drawBrush, drawRect, stringFormat);

                y += rowHeight;
            }
        }

        /// <summary>
        /// 获取一段字符串完全打印需要的高度
        /// </summary>
        /// <param name="drawString"></param>
        /// <param name="stringFormat"></param>
        /// <param name="drawFont"></param>
        /// <param name="graphics"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        private static float GetTrueHight(string drawString, StringFormat stringFormat, Font drawFont, Graphics graphics, float width, float height)
        {
            int chars; int lines;

            // 打印机范围 同 RectangleF 画布的 宽高
            SizeF layoutArea = new SizeF();
            layoutArea.Width = width;
            layoutArea.Height = height;

            // chars  在这个范围内实际会打印的字数
            // lines  在这个范围内实际会打印的行数
            // 得到的 chars 如果小于 drawString.length 说明 打印不全 需要增加高度(行) 再次尝试 直到 chars =  drawString.length 说明打印完整文字
            graphics.MeasureString(drawString, drawFont, layoutArea, stringFormat, out chars, out lines);

            Console.WriteLine($"chars:{chars}  lines:{lines}");

            if (chars < drawString.Length)
            {
                return GetTrueHight(drawString, stringFormat, drawFont, graphics, width, height += 25);
            }
            else
            {
                return height;
            }
        }
        #endregion

        #region###########商品小票打印#############
        /// <summary>
        /// 商品打印
        /// </summary>
        public static void Myprinter()
        {
            PrintDocument pd = new PrintDocument();
            pd.PrintPage += new PrintPageEventHandler(printDocument_PrintA4Page);
            //pd.DefaultPageSettings.PrinterSettings.PrinterName = "ZDesigner GX430t";//打印机名称
            //pd.DefaultPageSettings.Landscape = true;  //设置横向打印，不设置默认是纵向的
            pd.PrintController = new System.DrawingCore.Printing.StandardPrintController();
            pd.Print();
        }

        private static void printDocument_PrintA4Page(object sender, PrintPageEventArgs e)
        {
            string goodscode = "29000010014400001";
            Font titleFont = new Font("黑体", 11, FontStyle.Bold);//标题字体           
            Font fntTxt = new Font("宋体", 10, FontStyle.Regular);//正文文字         
            Font fntTxt1 = new Font("宋体", 8, FontStyle.Regular); //正文文字           
            Brush brush = new SolidBrush(Color.Black);//画刷           
            Pen pen = new Pen(Color.Black);           //线条颜色
            string filename = DateTime.Now.ToString("yyyyMMddHHmmssffffff")+".gif";
            string url = "D:\\项目\\项目功能模块\\ClassLibrary\\LabelPrint\\LabelPrint\\wwwroot\\images\\"+filename;
            try
            {
                e.Graphics.DrawString("西红柿", titleFont, brush, new Point(20, 10));
                Point[] points111 = { new Point(20, 28), new Point(220, 28) };
                e.Graphics.DrawLines(pen, points111);
                e.Graphics.DrawString("编号：", fntTxt, brush, new Point(20, 31));
                e.Graphics.DrawString("JT3456789123465", fntTxt, brush, new Point(60, 31));
                e.Graphics.DrawString("单价：", fntTxt, brush, new Point(20, 46));
                e.Graphics.DrawString("5元/千克", fntTxt, brush, new Point(60, 46));
                e.Graphics.DrawString(goodscode, fntTxt1, brush, new Point(270, 56));
                System.DrawingCore.Bitmap bitmap = MakeTXCode.CreateBarCode(goodscode, url, 120, 40);
                e.Graphics.DrawImage(bitmap, new Point(230, 10));

            }
            catch (Exception ee)
            {
                throw new Exception(ee.Message.ToString());
            }
        }
        #endregion
    }
}
